/*
 * Copyright (c) 2022  by Junzhao
 * THIS FILE IS PART OF JAVASE Song Huongkang PROJECT
 * All Rights Reserved.
 */

package Iterator迭代器接口;

import Collection接口.Person;
import org.junit.Test;

import java.util.*;

/**
 * @description Iterator迭代器接口
 *           集合元素的遍历
 *  Iterator对象称为迭代器(设计模式的一种)，主要用于遍历 Collection 集合中的元素。
 *  GOF给迭代器模式的定义为：提供一种方法访问一个容器(container)对象中各个元
 *  素，而又不需暴露该对象的内部细节。迭代器模式，就是为容器而生。类似于“公
 *  交车上的售票员”、“火车上的乘务员”、“空姐”。
 *  Collection接口继承了java.lang.Iterable接口，该接口有一个iterator()方法，那么所
 *  有实现了Collection接口的集合类都有一个iterator()方法，用以返回一个实现了
 *  Iterator接口的对象。
 *  Iterator 仅用于遍历集合，Iterator 本身并不提供承装对象的能力。如果需要创建
 *  Iterator 对象，则必须有一个被迭代的集合。
 *  集合对象每次调用iterator()方法都得到一个全新的迭代器对象，默认游标都在集合
 *  的第一个元素之前。
 *
 *  在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用，且
 * 下一条记录无效，直接调用it.next()会抛出NoSuchElementException异常。
 *
 *  注意：
 *  Iterator可以删除集合的元素，但是是遍历过程中通过迭代器对象的remove方
 *  法，不是集合对象的remove方法。
 *  如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法，
 *  再调用remove都会报IllegalStateException。
 *
 *
 *
 *
 *
 *
 * @author 俊昭
 * @date 2022/4/19
*/
public class IteratorTest {
    @Test
    public void test01(){
        Collection c1 = new ArrayList();
        c1.add("123");
        c1.add(456);
        c1.add(false);
        c1.add(new Person("张三",20));
        c1.add("tom");
        System.out.println(c1.toString());
        // [123, 456, false, Person{name='张三', age=20}, tom]




        // Iterator iterator() 对一个集合使用返回一个Iterator对象
        Iterator iterator1 = c1.iterator();

//        iterator1.remove();// IllegalStateException




        // 对Iterator对象操作
        // （一）穷举 不推荐
        // next() 返回迭代中的下一个元素。
//        System.out.println(iterator1.next());// 123
//        System.out.println(iterator1.next());// 456
//        System.out.println(iterator1.next());// false
//        System.out.println(iterator1.next());// Person{name='张三', age=20}
//        System.out.println(iterator1.next());// tom
//        System.out.println(iterator1.next());// NoSuchElementException(没有这样的元素)
        // 超过元素个数抛异常 迭代完成后迭代器中就没有元素了

        // （二）while循环
        // boolean hasNext() 如果迭代有更多的元素则返回true。
        // (换句话说，如果next返回一个元素而不是抛出异常，则返回true。)
        /*          //hasNext():判断是否还有下一个元素
            while(iterator.hasNext()){
                    //next():①指针下移 ②将下移以后集合位置上的元素返回
                System.out.println(iterator.next());
                }
        */
        while (iterator1.hasNext()){
            System.out.println(iterator1.next());
        }
        // 123 456 false Person{name='张三', age=20} tom 与上面结果是一样的

        // （三）for循环 不推荐
//        for (int i = 0; i < c1.size(); i++) {
//            System.out.println(iterator1.next());
//        }
        // 123 456 false Person{name='张三', age=20} tom 与上面结果是一样的

        // （四）增强for循环
        for (Object o : c1) {
            System.out.println(o);
        }
        // 123 456 false Person{name='张三', age=20} tom 与上面结果是一样的

        // remove()

        iterator1.remove();



    }
    @Test
    public void test02(){
        Collection c1 = new ArrayList();
        c1.add("123");
        c1.add(456);
        c1.add(false);
        c1.add(new Person("张三",20));
        c1.add("tom");
        Iterator iterator1 = c1.iterator();

        // 删除"tom"元素
        // void remove()
        // 从基础集合中移除此迭代器返回的最后一个元素
        while (iterator1.hasNext()){
            Object o = iterator1.next();
            if (o.equals("tom")){
                iterator1.remove();
            }
        }
        // c1.removeIf(o -> o.equals("tom")); 与上边等价

        // 遍历集合 需要重新生成一个迭代器
        Iterator iterator2 = c1.iterator();
        while (iterator2.hasNext()){
            System.out.println(iterator2.next());
        }
        // 123 456 false Person{name='张三', age=20}



    }
}
